package com.iqiyi.pps.epg.core.rpc.qipu.Composite;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iqiyi.pps.epg.api.model.web.program.TProgram;
import com.iqiyi.pps.epg.api.model.web.program.TProgramBase;
import com.iqiyi.pps.epg.core.async.AsyncService;
import com.iqiyi.pps.epg.core.async.HeartBeatCenter;
import com.iqiyi.pps.epg.core.async.IAsyncTask;
import com.iqiyi.pps.epg.core.async.IHeartBeat;
import com.iqiyi.pps.epg.core.model.channel.ChannelBase;
import com.iqiyi.pps.epg.core.model.control.ProgramPlatformControl;
import com.iqiyi.pps.epg.core.model.program.*;
import com.iqiyi.pps.epg.core.model.task.SimpleTask;
import com.iqiyi.pps.epg.core.model.task.SimpleTaskStatus;
import com.iqiyi.pps.epg.core.model.task.SimpleTaskType;
import com.iqiyi.pps.epg.core.service.broadcast.BroadcastControlService;
import com.iqiyi.pps.epg.core.service.channel.ChannelService;
import com.iqiyi.pps.epg.core.service.program.ProgramService;
import com.iqiyi.pps.epg.core.service.task.SimpleTaskService;
import com.iqiyi.pps.epg.core.utils.*;
import knowledge.pub.*;
import knowledge.pub.Properties;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.*;

/**
 * Created by karkarrotxu on 2014/12/27.
 */
@Service
public class NodeLiveEpisodeImpl implements InitializingBean {
    public final static int STATUS_IDLE = 1;
    public final static int STATUS_RUNNING = 2;

    public static final String LIVE_TEMP_OTHER = "live_temp_other";
    public static final String MULTI_LIVE_RESOURCE_ID = "multi_live_resource_id";

    public static final String FORMAT_SYNC = "[flag=%b][begin=%d][end=%d]";
    //  public static final String ONLINE_TEST_LIVEEPISODE = "online_test_liveepisode";
    public static final String QISU_URL_TEMPLATE = "qisu://tvid=;vid=%s;ischarge=%s;vtype=1";

    public static final String IS_SUPPORT_TVOD = "is_support_tvod";
    public static final String IS_SUPPORT_MONTHLY = "is_support_monthly";
    public static final String IS_SUPPORT_TVOD_COUPON = "is_support_tvod_coupon";
    public static final String IS_SUPPORT_PACKAGE = "is_support_package";
    public static final String PREVIEW_TYPE = "previewType";
    public static final String CHARGE_BASE = "charge_base";
    public static final String TVOD = "tvod";
    public static final String ORIGINAL_PRICE = "originalPrice";
    public static final String SETTLEMENT_PRICE = "settlementPrice";
    public static final String VALID_TIME = "validTime";
    public static final String CHARGEBASE_ORIGINAL_PRICE = "original_price";
    public static final String CHARGEBASE_SETTLEMENT_PRICE = "settlement_price";
    public static final String CHARGEBASE_VALID_TIME = "valid_time";

    private long restRepeatTime = 0l;
    private int dealOnce = 200;
    private int cycleRepeat = 20;
    private static final Logger logger = LoggerFactory.getLogger(NodeLiveEpisodeImpl.class);
    @Autowired
    private NodeCommonImpl commonImpl;
    @Autowired
    private ChannelService channelService;
    @Autowired
    private ProgramService programService;
    private int status = 0;
    @Autowired
    private SimpleTaskService simpleTaskService;

    @Autowired
    private BroadcastControlService broadcastControlService;

    private Set<Long> deleteChannelIdList = new HashSet<Long>();
    private List<ChannelBase> deleteAppendList = new ArrayList<ChannelBase>();

    private AsyncServiceImpl asyncService = new AsyncServiceImpl();

    private long syncSingle(TProgram tProgram, long fQipuId, int cliveType) {
        if (tProgram == null) {
            logger.info("[syncSingle]  tProgram is null");
            return -1;
        }
        Long entity = tProgram.getQipuId();
        if (entity < 1 && fQipuId < 1) {
            logger.info("[syncSingle]  illegal [entity={}][fQipuId={}]", entity, fQipuId);
            return -1;
        }
        try {
            boolean syncFlag = true;
            logger.info("[syncProgramDataList] sync start:" + tProgram.getId() + " qipuId:" + tProgram.getQipuId());
            if (tProgram.isOnlineStatus()) {
                int resultValue1 = writeLiveEpisodeToQipu(tProgram, fQipuId, cliveType);
                if (checkFail(resultValue1, "phase1 writeLiveEpisodeToQipu")) {
                    syncFlag = false;
                    //  return;
                }
                List<ProgramPlatformControl> controls = broadcastControlService.getProgramPlatformControls(tProgram.getId());
                if (controls.size() > 0) {
                    boolean resultValue2 = broadcastControlService.writeEpisodeNewQipu(tProgram.getQipuId(), tProgram.getTest() == 1 || tProgram.getType() == 7, controls);
                    if (checkFail(resultValue2 ? 0 : -1, "resultValue2 broadcastControlService.writeEpisodeNewQipu")) {
                        syncFlag = false;
                    }
                }
            } else {
                int resultValue4 = setLiveEpisodeFatherInfoToQipu(entity, tProgram, false, fQipuId);
                if (checkFail(resultValue4, "phase4 setLiveEpisodeFatherInfoToQipu")) {
                    syncFlag = false;
                    //  return;
                }
                int resultValue6 = commonImpl.setObjectDeletedToQipu(entity, true);
                if (checkFail(resultValue6, "phase6 commonImpl.setObjectDeletedToQipu")) {
                    syncFlag = false;
                    //  return;
                }

            }
            if (!syncFlag) {
                logger.info("[syncSingle] sync fail id:" + tProgram.getId() + " qipuId:" + tProgram.getQipuId());
                return -1;
            }
        } catch (Exception e) {
            logger.info("[syncSingle]  sync fail id:" + tProgram.getId() + " qipuId:" + tProgram.getQipuId());
            logger.error("[syncSingle]  error ", e);
        }

        return tProgram.getId();
    }

    public synchronized boolean isRunning() {
        return status == STATUS_RUNNING;
    }

    public void syncProgramData(TProgram tProgram, boolean syncFlag) {
        ChannelBase fatherChannelBase = channelService.getChannelBase(tProgram.getFatherId());
        long fQipuId = -1;
        if (fatherChannelBase == null || fatherChannelBase.getQipuId() == null || fatherChannelBase.getQipuId() == 0) {
            logger.warn("[NodeLiveEpisodeImpl][syncProgramData] fail case channel qipuId is zero");
            return;
        }
        fQipuId = fatherChannelBase.getQipuId();
        if (fatherChannelBase.getPanoFormat() != null) {
            tProgram.setPanoFormat(fatherChannelBase.getPanoFormat());
        }

        if (fatherChannelBase.getThreeD() != null) {
            tProgram.setThreeD(fatherChannelBase.getThreeD());
        }

        long returnValue = syncSingle(tProgram, fQipuId, fatherChannelBase.getLiveType());
        if (syncFlag) {
            List<Long> completeList = new ArrayList<Long>();
            completeList.add(returnValue);
            programService.syncComplete(completeList);
        }
    }


    public void forceSyncProgramDataList(long fatherId) {
        try {
            ChannelBase channelBase = channelService.getChannelBase(fatherId);
            Map<Long, ChannelBase> referMap = transToMap(channelBase);
            List<TProgram> list = programService.findNotSyncTProgram(fatherId);
            List<Long> completeList = new ArrayList<Long>();
            long returnValue = 0;
            // start new epg
            boolean hasValue = channelBase.getPanoFormat() != null;
            for (TProgram tProgram : list) {
                long fQipuId = referMap.get(tProgram.getFatherId()).getQipuId();
                if (hasValue) {
                    tProgram.setPanoFormat(channelBase.getPanoFormat());
                }
                returnValue = syncSingle(tProgram, fQipuId, channelBase.getLiveType());
                if (returnValue != -1) {
                    completeList.add(returnValue);
                }
            }
            logger.info("completeList size : " + completeList.size());
        } catch (Exception error) {
            logger.error("[NodeLiveEpisodeImpl][forceSyncProgramDataList][error]", error);
        }
    }

    public void syncProgramDataList(boolean syncFlag) {
        if (isRunning()) {
            restRepeatTime += cycleRepeat;
            logger.info("syncProgramDataList is running! restRepeatTime :" + cycleRepeat);
            return;
        }
        status = STATUS_RUNNING;
        restRepeatTime += cycleRepeat;
        try {
            logger.info("[syncProgramDataList] sync delete flag ");
            int effectDeleteNum = 0;
            deleteAppendList.clear();
            if (deleteChannelIdList.size() > 0) {
                effectDeleteNum = programService.syncProgramDelete(deleteChannelIdList.toString());
                List<Criterion> expressionList = new ArrayList<>();
                expressionList.add(Restrictions.in("id", deleteChannelIdList));
                List<ChannelBase> tempList = channelService.findChannelBaseList(expressionList);
                if (tempList != null) {
                    deleteAppendList.addAll(tempList);
                }
            }
            deleteChannelIdList.clear();
            logger.info("[syncProgramDataList] sync delete flag effectDeleteNum :" + effectDeleteNum);

            logger.info("[syncProgramDataList] recover sync fail status ");
            int effectNum = programService.recoverSyncStatus();
            logger.info("[syncProgramDataList] recover effectNum :" + effectNum);

            List<Criterion> expressionList = new ArrayList<>();
            expressionList.add(Restrictions.ne("isEnable", -1));
            expressionList.add(Restrictions.gt("qipuId", 0L));
            while (restRepeatTime > 0) {
                List<ChannelBase> channelBaseList = channelService.findChannelBaseList(expressionList);
                channelBaseList.addAll(deleteAppendList);
                Map<Long, ChannelBase> referMap = transToMap(channelBaseList);
                List<TProgram> list = programService.findNeedSyncTProgram(dealOnce);
                if (list.size() == 0) {
                    restRepeatTime = 0;
                    logger.info("[syncProgramDataList] list is zero interrupt loop ");
                    break;
                }
                List<Long> completeList = new ArrayList<Long>();

                long returnValue = 0;
                // start new epg
                ChannelBase channelBase = null;
                List<ProgramLog> programLogs = new ArrayList<ProgramLog>();
                long syncBegin = 0;
                for (TProgram tProgram : list) {
                    channelBase = referMap.get(tProgram.getFatherId());
                    if (channelBase != null) {
                        long fQipuId = channelBase.getQipuId();
                        if (channelBase.getPanoFormat() != null) {
                            tProgram.setPanoFormat(channelBase.getPanoFormat());
                        }
                        if (channelBase.getThreeD() != null) {
                            tProgram.setThreeD(channelBase.getThreeD());
                        }
                        syncBegin = System.currentTimeMillis();
                        returnValue = syncSingle(tProgram, fQipuId, channelBase.getLiveType());
                        programLogs.add(WriteSystemLogUtil.getInstance().getProgramLog(tProgram.getId(), Constants.LogType.PROGRAM_WRITE_QIPU.getIndex(), String.format(FORMAT_SYNC, returnValue > 0, syncBegin, System.currentTimeMillis())));
                        if (returnValue != -1) {
                            completeList.add(returnValue);
                        }
                        if (programLogs.size() >= 50) {
                            programService.saveProgramLogList(programLogs);
                            programLogs.clear();
                        }
                    } else {
                        deleteChannelIdList.add(tProgram.getFatherId());
                        logger.info("channelBase not exist id : " + tProgram.getFatherId());
                    }
                }
                if (programLogs.size() > 0) {
                    programService.saveProgramLogList(programLogs);
                }

                if (syncFlag) {
                    logger.info("completeList size : " + completeList.size());
                    programService.syncComplete(completeList);
                }
                restRepeatTime--;
            }

        } catch (Exception error) {
            logger.error("[NodeLiveEpisodeImpl][syncProgramDataList][error]", error);
        } finally {
            status = STATUS_IDLE;
        }
    }

    private Map<Long, ChannelBase> transToMap(ChannelBase channelBase) {
        List<ChannelBase> list = new ArrayList<ChannelBase>();
        if (channelBase != null) {
            list.add(channelBase);
        }
        return transToMap(list);
    }

    private Map<Long, ChannelBase> transToMap(List<ChannelBase> list) {
        Map<Long, ChannelBase> map = new HashMap<Long, ChannelBase>();
        List<ChannelBase> waitRegisterList = new ArrayList<ChannelBase>();
        for (ChannelBase temp : list) {
//            if (temp.getIsEnable() == 0) {
//                continue;
//            }
            if (temp.getQipuId() == 0) {
                waitRegisterList.add(temp);
            } else {
                map.put(temp.getId(), temp);
            }
        }
        if (waitRegisterList.size() > 0) {
            logger.warn("[NodeLiveEpisodeImpl] need register channel qipuId :" + waitRegisterList.toString());
        }
        return map;
    }

    private boolean checkFail(int resultValue, String phaseKey) {
        if (resultValue == -1) {
            logger.info("[ProgramSyncTrigger] fail on phaseKey : " + phaseKey);
            return true;
        }
        return false;
    }


    /*
        写入轮播台逻辑
     */
    private void setCarouselInfo(Properties.LiveEpisodeBase.Builder builderLiveEpisodeBase, TProgram tProgram) {
        builderLiveEpisodeBase.setIsLive(ProgramData.TYPE_LIVE.intValue() == tProgram.getLive());
        Metadatas.MetaSummary.Builder summaryBuilder = Metadatas.MetaSummary.newBuilder();
        if (tProgram.getDescription() != null) {
            summaryBuilder.setDesc(tProgram.getDescription());
        }
        summaryBuilder.setEntityId(tProgram.getCarouselEpisode());
        builderLiveEpisodeBase.addCarouselEpisodeSummary(summaryBuilder.build());

    }

    public int setLiveEpisodeFatherInfoToQipu(Long entityId, TProgram tProgram, boolean isValid, long fatherQipuId) {
        Knowledge.LiveEpisode.Builder builder = commonImpl.newLiveEpisodeBuilder(entityId);
        builder.addFatherLiveChannel(getFatherInfo(isValid, fatherQipuId, tProgram));
        return commonImpl.writeEntity(builder.build());
    }

    public Common.FatherInfo.Builder getFatherInfo(boolean isValid, long fatherQipuId, TProgram tProgram) {
        Common.FatherInfo.Builder builderFatherInfo = Common.FatherInfo.newBuilder();
        builderFatherInfo.setDesc(tProgram.getPname());
        builderFatherInfo.setFatherId(fatherQipuId);
        builderFatherInfo.setBrand(Common.Brand.IQIYI_PPS);
        builderFatherInfo.setCreateTime(DateTimeUtil.parseLongFormat(tProgram.getAddTime()));
        builderFatherInfo.setIsValid(isValid);
        //* 暂时使用tProgramId 代替
        builderFatherInfo.setChildOrder((int) tProgram.getId());
        builderFatherInfo.setShouldNotifyChangeOfFather(true);
        return builderFatherInfo;
    }

    public int writeLiveEpisodeToQipu(TProgram tProgram, long fQipuId, int cliveType) {
        Long entityId = tProgram.getQipuId();
        Knowledge.LiveEpisode.Builder liveBuilder = commonImpl.newLiveEpisodeBuilder(entityId);
        Knowledge.LiveEpisode oldData = commonImpl.getLiveEpisode(tProgram.getQipuId());
        JSONObject bossInfo = null;

        try {
            bossInfo = JSON.parseObject(tProgram.getBossInfo());
        } catch (Exception e) {
            logger.info("programQipuId={},bossInfo={} data error", tProgram.getQipuId(), tProgram.getBossInfo());
        }

        fillLiveEpisodeMetadata(tProgram, liveBuilder);
        boolean canWrite = checkCanWriteEpisodeSummary(tProgram);
        long oldEpisodeSummary = 0;
        if (oldData != null && oldData.getEpisodeSummary() != null && oldData.getEpisodeSummary().getEntityId() > 0) {
            oldEpisodeSummary = oldData.getEpisodeSummary().getEntityId();
        }
        fillLiveEpisodeBase(tProgram, liveBuilder, canWrite, cliveType);
        fillPanoFormat(tProgram, liveBuilder);
        fillThreeD(tProgram, liveBuilder);
        if (!canWrite) {
            asyncService.addAsyncTask(tProgram);
        }
        if (liveBuilder.getEpisodeSummary().getEntityId() != oldEpisodeSummary) {
            if (liveBuilder.getEpisodeSummary().getEntityId() == 0 || canWrite) {
                WriteSystemLogUtil.getInstance().writeProgramLog(tProgram.getId(), Constants.LogType.WRITE_EPISODE_SUMMARY.getIndex(), "old:" + oldEpisodeSummary + "; new:" + liveBuilder.getEpisodeSummary().getEntityId() + "");
            }
        }
        liveBuilder.setQitan(commonImpl.getQitan(tProgram.getQitanId(), tProgram.isAllowComment()));
        liveBuilder.addFatherLiveChannel(getFatherInfo(true, fQipuId, tProgram));
        fillLiveEpisodeBoss(tProgram, liveBuilder, bossInfo);
        fillLiveEpisodeChargeBase(tProgram, liveBuilder, bossInfo);
        fillProgramQisu(tProgram, liveBuilder);
        fillLiveEpisodeSport(tProgram, liveBuilder);
        fillMatchSummary(tProgram, liveBuilder);
        fillVoteSummary(tProgram, liveBuilder);
        fillProgramLogo(tProgram, liveBuilder);
        fillAdvert(tProgram, liveBuilder);
        if (tProgram.getBarCode() != null) {
            fillPuyu(tProgram, liveBuilder);
        }
        fillProgramSubscribe(tProgram, liveBuilder);
        fillNoticeTimes(tProgram, liveBuilder);
        fillChatRoom(tProgram, liveBuilder);
        fillDaoju(tProgram, liveBuilder);
        fillLiveTempOther(tProgram, liveBuilder);
        fillResourceId(tProgram, liveBuilder);
        fillProgramTag(tProgram, liveBuilder);
        //  fillOnlineTest(tProgram, liveBuilder);
        Knowledge.LiveEpisode.Builder deleteBuilder = clearQipuOldData(tProgram, oldData);


        if (deleteBuilder != null) {
            return commonImpl.setEntity(liveBuilder.build(), deleteBuilder.build());
        } else {
            return commonImpl.writeEntity(liveBuilder.build());
        }
    }

    public void fillNoticeTimes(TProgram tProgram, Knowledge.LiveEpisode.Builder builder) {
        if (tProgram.getNoticeStartTime() != null) {
            builder.setNoticeStartTime(DateTimeUtil.parseLongFormat(tProgram.getNoticeStartTime()));
        }
        if (tProgram.getNoticeStopTime() != null) {
            builder.setNoticeEndTime(DateTimeUtil.parseLongFormat(tProgram.getNoticeStopTime()));
        }
    }

    public void fillChatRoom(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        Properties.ChatRoomSummary.Builder chatRoom = Properties.ChatRoomSummary.newBuilder();
        chatRoom.setShouldDisplay(tProgram.getChatDisplay() == 1);
        chatRoom.setIsEnable(tProgram.getChatEnable() == 1);
        if (!chatRoom.getIsEnable()) {
            chatRoom.setShouldDisplay(false);
        }
        if (tProgram.getChatRoomId() > 0) {
            chatRoom.setChatRoomId(tProgram.getChatRoomId());
        }
        if (ProgramData.CHAT_RIGHTS_MAP.containsKey(tProgram.getChatRights())) {
            chatRoom.setChatRights(ProgramData.CHAT_RIGHTS_MAP.get(tProgram.getChatRights()));
        }
        chatRoom.setIsSendFake(tProgram.getChatFake() == 1);
        chatRoom.setShowPopups(tProgram.getChatPopups() == 1);
        liveBuilder.setChatRoomSummary(chatRoom);
    }

    public void fillDaoju(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        Metadatas.Prop.Builder daoju = Metadatas.Prop.newBuilder();
        if (tProgram.getDaojuId() != null) {
            daoju.setChannelCode(tProgram.getDaojuId());
        }
        daoju.setIsEnabled(tProgram.getDaojuEnable() == 1);
        liveBuilder.setProp(daoju);

    }

    public void fillLiveEpisodeMetadata(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        Metadatas.LiveEpisodeMetadata.Builder builder = Metadatas.LiveEpisodeMetadata.newBuilder();
        if (tProgram.getDescription() != null) {
            builder.setDescription(tProgram.getDescription());
        }
        builder.setProgramName(tProgram.getPname());
        builder.setStartPlayTime(DateTimeUtil.parseLongFormat(tProgram.getStartPlayTime()));
        builder.setStopPlayTime(DateTimeUtil.parseLongFormat(tProgram.getEndPlayTime()));

        if (tProgram.getStreamStartPlayTime() != null) {
            builder.setStartStreamTime(DateTimeUtil.parseLongFormat(tProgram.getStreamStartPlayTime()));
        }
        if (tProgram.getStreamEndPlayTime() != null) {
            builder.setEndStreamTime(DateTimeUtil.parseLongFormat(tProgram.getStreamEndPlayTime()));
        }

        if (StringUtils.isNotEmpty(tProgram.getTag())) {
            String[] tags = tProgram.getTag().split(",");
            for (String tag : tags) {
                builder.addTag(tag);
            }
        }

        liveBuilder.setMetadata(builder);
    }

    public Knowledge.LiveEpisode.Builder clearQipuOldData(TProgram tProgram, Knowledge.LiveEpisode oldData) {

        Knowledge.LiveEpisode.Builder deleteBuilder = commonImpl.newLiveEpisodeBuilder(tProgram.getQipuId());
        boolean useDelete = false;
        if (oldData != null) {
            // clear vote summary
            List<Metadatas.VoteSummary> voteSummaryList = oldData.getVoteSummaryList();
            if (voteSummaryList.size() > 0) {
                useDelete = true;
                deleteBuilder.addAllVoteSummary(voteSummaryList);
                //  return deleteBuilder;
            }
            // clear clearCategory
            List<Metadatas.CategorySummary> categoryList = oldData.getCategorySummaryList();
            if (categoryList.size() > 0) {
                useDelete = true;
                deleteBuilder.addAllCategorySummary(categoryList);
            }
            /* clear key value pair
            * LIVE_TEMP_OTHER
            *MULTI_LIVE_RESOURCE_ID
             */
            List<Common.KeyValuePair> keyValuePairList = oldData.getKeyValuePairList();
            if (keyValuePairList.size() > 0) {
                Common.KeyValuePair fromQipu_LIVE_TEMP_OTHER = null;
                Common.KeyValuePair fromQipu_MULTI_LIVE_RESOURCE_ID = null;
                //  Common.KeyValuePair onlineTest = null;
                for (Common.KeyValuePair temp : keyValuePairList) {
                    switch (temp.getName()) {
                        case LIVE_TEMP_OTHER:
                            fromQipu_LIVE_TEMP_OTHER = temp;
                            break;
                        case MULTI_LIVE_RESOURCE_ID:
                            fromQipu_MULTI_LIVE_RESOURCE_ID = temp;
                            break;
                        default:
                            break;
                    }
                }
                if (fromQipu_LIVE_TEMP_OTHER != null) {
                    List<TProgramBase> list = tProgram.getRelationList();
                    boolean hasLocalData = false;
                    if (list != null && list.size() > 0) {
                        for (TProgramBase tBase : list) {
                            if (tBase.getType() == 201) {
                                hasLocalData = true;
                                break;
                            }
                        }
                    }
                    if (!hasLocalData) {
                        useDelete = true;
                        deleteBuilder.addKeyValuePair(fromQipu_LIVE_TEMP_OTHER);
                    }
                }
                if (fromQipu_MULTI_LIVE_RESOURCE_ID != null) {
                    if (StringUtils.isBlank(tProgram.getResourceId())) {
                        useDelete = true;
                        deleteBuilder.addKeyValuePair(fromQipu_MULTI_LIVE_RESOURCE_ID);
                    }
                }
            }
            // clear passport id
            if (oldData.getBase().hasPassportId()) {
                boolean hasPassportData = false;
                List<TProgramBase> list = tProgram.getRelationList();
                if (list != null && list.size() > 0) {
                    for (TProgramBase tBase : list) {
                        if (tBase.getType() == 301) {
                            hasPassportData = true;
                            break;
                        }
                    }
                }
                if (!hasPassportData) {
                    useDelete = true;
                    deleteBuilder.setBase(oldData.getBase());
                }
            }

            //clear match_summary
            if (oldData.hasMatchSummary() && tProgram.getMatchSummary() == null) {
                useDelete = true;
                deleteBuilder.setMatchSummary(oldData.getMatchSummary());
            }

            // clear advert summary
            List<Metadatas.AdSummary> adSummaryList = oldData.getAdSummaryList();
            if (adSummaryList.size() > 0) {
                useDelete = true;
                deleteBuilder.addAllAdSummary(adSummaryList);
                //  return deleteBuilder;
            }

            // clear old tags
            if (oldData != null && oldData.getTagCount() > 0) {
                useDelete = true;
                deleteBuilder.addAllTag(oldData.getTagList());
            } else {
                logger.info("[delAllTags][entityId={}][isNull={}] skip case no tag", tProgram.getQipuId(), oldData == null);
            }
        }
        return useDelete ? deleteBuilder : null;
    }

    public void fillPassportId(TProgram tProgram, Properties.LiveEpisodeBase.Builder liveBaseBuilder) {
        List<TProgramBase> list = tProgram.getRelationList();
        if (list != null && list.size() > 0) {
            for (TProgramBase tBase : list) {
                if (tBase.getType() == 301) {
                    logger.info("programId={},passprotId={}", tProgram.getId(), tBase.getValue());
                    liveBaseBuilder.setPassportId(Long.valueOf(tBase.getValue()));
                    break;
                }
            }
        }
    }

    public void fillCategory(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder, Properties.LiveEpisodeBase.Builder liveBaseBuilder) {
        Metadatas.CategorySummary.Builder categorySummary = null;
        if (tProgram.getCategory() != null && tProgram.getCategory().length() > 0) {
            List<CategoryData> nodeList = JSONArray.parseArray(tProgram.getCategory(), CategoryData.class);
            Map<String, CategoryData> map = new HashMap<String, CategoryData>(64);
            CategoryData parent = null;
            for (CategoryData node : nodeList) {
                if (node.getDataMode() == 0) {
//                    map.put(node.getLevel() + "_" + node.getId(), node);
                    if (node.getLevel() == 1) {
                        liveBaseBuilder.setChannelId((int) node.getId());
                    } else if (node.getLevel() > 1) {
//                        parent = map.get((node.getLevel() - 1) + "_" + node.getPid());
//                        if (parent != null) {
//                            parent.addChild(node);
//                        }
                    }
                } else {
                    map.put("tag1_" + node.getId(), node);
                }

            }
            Iterator<Map.Entry<String, CategoryData>> it = map.entrySet().iterator();
            Map.Entry<String, CategoryData> element = null;
            CategoryData entity = null;
            while (it.hasNext()) {
                element = it.next();
                entity = element.getValue();
                if (!element.getValue().hasChildren()) {
                    categorySummary = Metadatas.CategorySummary.newBuilder();
                    categorySummary.setCategoryId(entity.getId() * 100 + 33);
//                    categorySummary.setName(entity.getName());
//                    categorySummary.setLevel(entity.getLevel());
                    liveBuilder.addCategorySummary(categorySummary);
                }
            }
        }
    }

    public void fillVoteSummary(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        //
        Metadatas.VoteSummary.Builder voteBuilder = null;
        List<TProgramBase> list = tProgram.getRelationList();
        if (list != null && list.size() > 0) {
            for (TProgramBase tBase : list) {
                if (tBase.getType() == 106) {
                    voteBuilder = Metadatas.VoteSummary.newBuilder();
                    voteBuilder.setVoteId(tBase.getKey());
                    voteBuilder.setVoteType(Metadatas.VoteType.PK_VOTE);
                    liveBuilder.addVoteSummary(voteBuilder);
                } else if (tBase.getType() == 107) {
                    voteBuilder = Metadatas.VoteSummary.newBuilder();
                    voteBuilder.setVoteId(tBase.getKey());
                    voteBuilder.setVoteType(Metadatas.VoteType.RANKING_VOTE);
                    liveBuilder.addVoteSummary(voteBuilder);
                }
            }
        }
    }

    //
    public int setLiveEpisodeBaseToQipu(TProgram tProgram) {
        Knowledge.LiveEpisode.Builder builder = commonImpl.newLiveEpisodeBuilder(tProgram.getQipuId());
        fillLiveEpisodeBase(tProgram, builder, true, 2);
        return commonImpl.writeEntity(builder.build());
    }

    private Properties.LiveEpisodeBase.Builder getLiveEpisodeBaseBuilder(TProgram tProgram, boolean canWrite) {
        Properties.LiveEpisodeBase.Builder builder = Properties.LiveEpisodeBase.newBuilder();
        builder.setType(Common.LiveProgramType.valueOf(tProgram.getType()));
        builder.setAllowPopups(tProgram.isAllowPopups());
        if (tProgram.getAudioChannel() != null) {
            builder.setAudioChannel(tProgram.getAudioChannel());
        }

        if (tProgram.getLeftChannel() != null) {
            builder.setLeftAudioChannel(tProgram.getLeftChannel());
        }

        if (tProgram.getRightChannel() != null) {
            builder.setRightAudioChannel(tProgram.getRightChannel());
        }

        if (tProgram.getWeiboTopic() != null) {
            builder.addWeiboTopic(tProgram.getWeiboTopic());
        }
        if (tProgram.getPageUrl() != null) {
            builder.setPageUrl(tProgram.getPageUrl());
        }

        builder.setQitanId((int) tProgram.getQitanId());
        builder.setWaterMarkFlag(tProgram.isWaterMarkFlag());

        if (tProgram.getLogoHidden() != null) {
            JSONObject logoHiddenJson = JSON.parseObject(tProgram.getLogoHidden());
            Collection collection = logoHiddenJson.values();
            for (Object obj : collection) {
                builder.addLogoHidden(Common.LogoHidden.valueOf(Integer.parseInt(obj.toString())));
            }
        }
        builder.setVideoPieceLength(tProgram.getVideoPieceLength());

        Metadatas.Metadata.Contributor.Builder builderContributor = Metadatas.Metadata.Contributor.newBuilder();
        List<TProgramBase> list = tProgram.getRelationList();
        if (list != null && list.size() > 0) {
            int type2Index = 1;
            for (TProgramBase tBase : list) {
                if (tBase.getType() == 1) {
                    Metadatas.Metadata.Contributor.DescriptionOfContributor.Builder descriptionBuilder = Metadatas.Metadata.Contributor.DescriptionOfContributor.newBuilder();
                    descriptionBuilder.setIdOfContributor(tBase.getKey());
                    descriptionBuilder.setNameOfContributor(tBase.getValue());
                    builderContributor.addDescriptionOfContributor(descriptionBuilder);
                    // old 2 ,now is 7
                } else if (tBase.getType() == 7) {
                    if (!canWrite) {
                        continue;
                    }
                    //wait to do
                    Metadatas.MetaSummary.Builder summaryBuilder = Metadatas.MetaSummary.newBuilder();
                    summaryBuilder.setDesc("");
                    summaryBuilder.setEntityId(tBase.getKey());
                    summaryBuilder.setOrder(type2Index);
                    builder.addEpisodeSummary(summaryBuilder);
                    type2Index++;
                } else if (tBase.getType() == 5) {
                    Metadatas.MetaSummary.Builder summaryBuilder = Metadatas.MetaSummary.newBuilder();
                    summaryBuilder.setDesc("");
                    summaryBuilder.setEntityId(tBase.getKey());
                    //    summaryBuilder.setOrder(type2Index);
                    builder.addEpisodeStartSummay(summaryBuilder);
                } else if (tBase.getType() == 6) {
                    Metadatas.MetaSummary.Builder summaryBuilder = Metadatas.MetaSummary.newBuilder();
                    summaryBuilder.setDesc("");
                    summaryBuilder.setEntityId(tBase.getKey());
                    //    summaryBuilder.setOrder(type2Index);
                    builder.addEpisodeEndSummary(summaryBuilder);
                }
            }
        }

        fillTabControl(tProgram, builder);

        builder.addContributor(builderContributor);
        builder.setExclusiveStatusIqiyi(tProgram.isQiyiExclusive());
        builder.setIsQiyiProduced(tProgram.isQiyiProduct());
        builder.setProvider(Common.ProviderType.PPC_TYPE);
        builder.setStreamMountType(Common.StreamMountType.MOUNT_CHANEL);
        return builder;
    }

    public void fillTabControl(TProgram tProgram, Properties.LiveEpisodeBase.Builder builder) {
        if (StringUtils.isBlank(tProgram.getTabControls())) {
            return;
        }

        try {
            JSONArray tabControls = JSON.parseArray(tProgram.getTabControls());

            for (int i = 0; i < tabControls.size(); i++) {
                Properties.LiveEpisodeTabControl.Builder tabBuilder = Properties.LiveEpisodeTabControl.newBuilder();
                JSONObject tab = tabControls.getJSONObject(i);
                if (tab.containsKey("type")) {
                    int type = tab.getIntValue("type");
                    tabBuilder.setTabType(Common.LiveEpisodeTabType.valueOf(type));

                    if (type == Common.LiveEpisodeTabType.LIVE_EPISODE_TAB_TYPE_ACTIVITY_VALUE) {
                        if (tab.containsKey("url")) {
                            tabBuilder.setActivityUrl(tab.getString("url"));
                        }
                    }
                } else {
                    continue;
                }

                if (tab.containsKey("display_name")) {
                    tabBuilder.setTabName(tab.getString("display_name"));
                }

                if (tabBuilder.getTabType() == Common.LiveEpisodeTabType.LIVE_EPISODE_TAB_TYPE_CHAT_ROOM) {
                    tabBuilder.setIsDisplayTab(tProgram.getChatDisplay() == 1);
                } else if (tab.containsKey("is_enable")) {
                    int is_enable = tab.getIntValue("is_enable");
                    tabBuilder.setIsDisplayTab(is_enable == 1);
                }

                if (tab.containsKey("is_default")) {
                    int is_default = tab.getIntValue("is_default");
                    tabBuilder.setIsDefaultTab(is_default == 1);
                }

                builder.addTabControl(tabBuilder);
            }
        } catch (Exception e) {
            logger.info("[fillTabControl] exception = " + e);
        }

    }

    public void doApiCheckNotify(TProgram tProgram, Knowledge.LiveEpisode.Builder builder) {
        try {
            long newChatRoomId = tProgram.getChatRoomId();
            long newEpisodeId = builder.getEpisodeSummary().getEntityId();
            Knowledge.LiveEpisode oldData = commonImpl.getLiveEpisode(tProgram.getQipuId());
            long oldEpisodeSummary = 0;
            if (oldData != null && oldData.getEpisodeSummary() != null && oldData.getEpisodeSummary().getEntityId() > 0) {
                oldEpisodeSummary = oldData.getEpisodeSummary().getEntityId();
            }
            logger.info("qipuId:{}, newChatRoomId:{},newEpisodeId:{},oldEpisodeSummary:{}", builder.getId(), newChatRoomId, newEpisodeId, oldEpisodeSummary);
            if (newChatRoomId != 0 && newEpisodeId != 0 && newEpisodeId != oldEpisodeSummary) {
                ApiChatUtil.packageHistoryMessage(
                        tProgram.getId(),
                        newChatRoomId,
                        builder.getId(),
                        newEpisodeId,
                        builder.getBase().getChannelId(),
                        DateTimeUtil.parseLongFormat(tProgram.getStartPlayTime()),
                        DateTimeUtil.parseLongFormat(tProgram.getEndPlayTime())
                );
            }
        } catch (Exception e) {
            logger.error("doApiCheckNotify", e);
        }
    }

    public void fillLiveEpisodeBase(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder, boolean canWrite, int cliveType) {
        Properties.LiveEpisodeBase.Builder builder = getLiveEpisodeBaseBuilder(tProgram, canWrite);
        if (Common.LiveProgramType.CAROUSEL_PROGRAM_VALUE == tProgram.getType()) {      //轮播台类型
            setCarouselInfo(builder, tProgram);
        }
//        Common.LogoHidden leftDown = Common.LogoHidden.valueOf("LOGO_HIDDEN_LEFT_DOWN");
//        Common.LogoHidden leftDown = Common.LogoHidden.valueOf("LOGO_HIDDEN_LEFT_DOWN");
//        builder.addLogoHidden(0,leftDown);
        builder.setPlayStatus(ProgramData.PLAY_STATUS_MAP.get(tProgram.getPlayStatus()));
        builder.setRecommendRate(tProgram.getRecommendRate());
        builder.setRecommendRemark(null == tProgram.getRecommendRemark() ? "" : tProgram.getRecommendRemark());
        builder.setSubjectUrl(null == tProgram.getSubjectUrl() ? "" : tProgram.getSubjectUrl());
        builder.setMaxPlaybackPeriod(tProgram.getMaxPlaybackPeriod());
        //添加精彩推荐字段 by justin
        builder.setIsDisplayRecommend(tProgram.getDisplayRecommend() == 1);
        if (tProgram.getPublicLevel() > -1) {
            Common.PublicLevel publicLevel = Common.PublicLevel.valueOf(tProgram.getPublicLevel());
            if (publicLevel != null) {
                builder.setPublicLevel(publicLevel);
            }
        }

        if (ProgramData.SALE_TYPE_MAP.containsKey(tProgram.getProjectType())) {
            builder.setSaleType(ProgramData.SALE_TYPE_MAP.get(tProgram.getProjectType()));
        }

        fillCategory(tProgram, liveBuilder, builder);
        fillPassportId(tProgram, builder);

        //add by lyk for episode root summary 2016-04-11
        if (builder.getEpisodeSummaryCount() > 0) {
            Metadatas.MetaSummary.Builder summaryBuilder = Metadatas.MetaSummary.newBuilder();
            summaryBuilder.setDesc("");
            summaryBuilder.setEntityId(builder.getEpisodeSummary(0).getEntityId());
            summaryBuilder.setOrder(0);
            liveBuilder.setEpisodeSummary(summaryBuilder);
        } else {
            delEpisodeSummaryToQipu(tProgram);
        }
        if (cliveType == 2) {
            builder.setIsOnlineTest(tProgram.getTest() == 1);
        }
        liveBuilder.setBase(builder);
        //确定新的点播id 产生,并且不同于旧的,发送聊天室弹幕收集请求
        doApiCheckNotify(tProgram, liveBuilder);
    }

    public void fillPanoFormat(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        String panoFormat = tProgram.getPanoFormat();
        Formats.PanoFormat.Builder panoBuilder = Formats.PanoFormat.newBuilder();
        if (panoFormat != null) {
            JSONObject panoObject = JSONObject.parseObject(panoFormat);
            if (panoObject.containsKey("videoType")) {
                panoBuilder.setVideoType(Formats.PanoFormat.VideoType.valueOf(panoObject.getIntValue("videoType")));
            } else {
                logger.info("[NodeLiveEpisodeImpl][fillPanoFormat] not contains videoType ");
                return;
            }
            panoBuilder.setViewAngleX(panoObject.getIntValue("angleX"));
            panoBuilder.setViewAngleY(panoObject.getIntValue("angleY"));
            if (panoObject.containsKey("zoomRate")) {
                panoBuilder.setZoomRate(panoObject.getFloatValue("zoomRate"));
            } else {
                panoBuilder.setZoomRate(1.0f);
            }
            liveBuilder.setPanoFormat(panoBuilder);
        }
    }

    public void fillThreeD(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        String threeD = tProgram.getThreeD();
        if (threeD != null) {
            Formats.ThreeDFormat.Builder threeDBuilder = Formats.ThreeDFormat.newBuilder();
            if (threeD != null) {
                JSONObject threeDObject = JSONObject.parseObject(threeD);
                if (threeDObject != null && threeDObject.containsKey("videoType")) {
                    threeDBuilder.setThreeDType(Common.ThreeDType.valueOf(threeDObject.getIntValue("videoType")));
                } else {
                    logger.info("[QipuManager][fillThreeD] not contains videoType ");
                    return;
                }
            }
            liveBuilder.setThreeDFormat(threeDBuilder);
        }

    }

    public int delEpisodeSummaryToQipu(TProgram tProgram) {
        Knowledge.LiveEpisode.Builder builderEpisode = commonImpl.newLiveEpisodeBuilder(tProgram.getQipuId());
        Metadatas.MetaSummary.Builder summaryBuilder = Metadatas.MetaSummary.newBuilder();
        summaryBuilder.setEntityId(0);
        builderEpisode.setEpisodeSummary(summaryBuilder);
        return commonImpl.deleteEntity(builderEpisode.build());
    }

    public boolean checkCanWriteEpisodeSummary(TProgram tProgram) {
        List<TProgramBase> list = tProgram.getRelationList();
        if (list != null) {
            for (TProgramBase tbase : list) {
                if (tbase.getType() == 7) {
                    JSONObject dataEntity = ApiQipuUtil.rpcReadQipuEntity(tbase.getKey());
                    return ApiQipuUtil.checkHasPPSControlAndAccessControl(dataEntity);
                }
            }
        }
        return true;
    }

    public void fillLiveEpisodeBoss(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder, JSONObject bossInfo) {
        Properties.Boss.Builder boss = Properties.Boss.newBuilder();

        // 设置付费信息
        boss.setIsMemberOnly(tProgram.isMemberOnly()); // 是否会员视频(0:不是,1;是)
        boss.setIsMemeberFree(tProgram.isMemberFree()); // 是否付费(0:付费,1:免费)
        // 划价状态(PAIED_AVAILABLE:付费已划价 PAIED_NOT_AVAILABLE :付费未划价 FREE :免费)
        boss.setStatus(Properties.Boss.Status.valueOf(tProgram.getBossStatus()));
//        if (boss.getStatus() != Properties.Boss.Status.FREE) {
//            boss.setPaidStartTime(DateTimeUtil.parseLongFormat(tProgram.getPaidStartTime())); // 付费开始时间
//            boss.setPaidEndTime(DateTimeUtil.parseLongFormat(tProgram.getPaidEndTime())); // 付费结束时间
//        }
        logger.info("[fillLiveEpisodeBoss][charge_status] " + Properties.Boss.ChargeStatus.valueOf(tProgram.getChargeStatus()));
        boss.setChargeStatus(Properties.Boss.ChargeStatus.valueOf(tProgram.getChargeStatus()));

        boss.addVipType(Common.VipType.valueOf(tProgram.getVipType()));

        if (null != bossInfo) {
            if (bossInfo.containsKey(PREVIEW_TYPE)) {
                int previewType = bossInfo.getIntValue(PREVIEW_TYPE);
                if (previewType == 1) {
                    boss.setIsFreeProbation(true);
                    boss.setFreeProbationType(Properties.Boss.FreeProbationType.FULL_PROBATION);
                } else if (previewType == 2) {
                    boss.setIsFreeProbation(false);
                    boss.setFreeProbationType(Properties.Boss.FreeProbationType.SIX_MINUTES_PROBATION);
                } else if (previewType == 0) {
                    boss.setIsFreeProbation(false);
                    boss.setFreeProbationType(Properties.Boss.FreeProbationType.NO_PROBATION);
                }
            }

            if (bossInfo.containsKey(IS_SUPPORT_TVOD)) {
                boss.setIsSupportTvod(bossInfo.getBooleanValue(IS_SUPPORT_TVOD));
            }

            if (bossInfo.containsKey(IS_SUPPORT_MONTHLY)) {
                boss.setIsSupportMonthly(bossInfo.getBooleanValue(IS_SUPPORT_MONTHLY));
            }

            if (bossInfo.containsKey(IS_SUPPORT_TVOD_COUPON)) {
                boss.setIsSupportTvodCoupon(bossInfo.getBooleanValue(IS_SUPPORT_TVOD_COUPON));
            }

            if (bossInfo.containsKey(IS_SUPPORT_PACKAGE)) {
                boss.setIsSupportPackage(bossInfo.getBooleanValue(IS_SUPPORT_PACKAGE));
            }

            if (bossInfo.containsKey(TVOD)) {
                Properties.Boss.Tvod.Builder tvodBuilder = Properties.Boss.Tvod.newBuilder();
                JSONObject tvodObject = bossInfo.getJSONObject(TVOD);
                if (tvodObject.containsKey(ORIGINAL_PRICE)) {
                    tvodBuilder.setOriginalPrice(tvodObject.getIntValue(ORIGINAL_PRICE));
                }

                if (tvodObject.containsKey(SETTLEMENT_PRICE)) {
                    tvodBuilder.setSettlementPrice(tvodObject.getIntValue(SETTLEMENT_PRICE));
                }

                if (null != tvodObject.getString(VALID_TIME)) {
                    tvodBuilder.setValidTime(tvodObject.getString(VALID_TIME));
                }

                boss.setTvod(tvodBuilder);
            }
        }

        liveBuilder.setBoss(boss);
    }

    public void fillLiveEpisodeChargeBase(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder,
                                          JSONObject bossInfo) {
        if (null == bossInfo) {
            logger.info("[NodeLiveEpisodeImpl][fillLiveEpisodeChargeBase][programQipuId={}] bossInfo is null", tProgram.getQipuId());
            return;
        }

        Properties.ChargeBase.Builder chargeBaseBuilder = Properties.ChargeBase.newBuilder();
        if (!bossInfo.containsKey(CHARGE_BASE)) {
            logger.info("[NodeLiveEpisodeImpl][fillLiveEpisodeChargeBase][programQipuId={}] do not contain charge_base info", tProgram.getQipuId());
            return;
        }

        JSONObject chargeBaseInfo = bossInfo.getJSONObject(CHARGE_BASE);
        if (null != chargeBaseInfo.getString("pay_mark")) {
            chargeBaseBuilder.setPayMark(Common.PayMark.valueOf(chargeBaseInfo.getString("pay_mark")));
        }
        if (StringUtils.isNotBlank(chargeBaseInfo.getString("pay_mark_url"))) {
            chargeBaseBuilder.setPayMarkUrl(chargeBaseInfo.getString("pay_mark_url"));
        }

        if (null != chargeBaseInfo.getString("pay_type")) {
            chargeBaseBuilder.setPayType(Properties.ChargeBase.PayType.valueOf(
                    "PAY_TYPE_" + chargeBaseInfo.getString("pay_type").toUpperCase()));
        }

        if (chargeBaseInfo.containsKey("charge_control")) {
            JSONArray chargeControl = chargeBaseInfo.getJSONArray("charge_control");
            Iterator<Object> t = chargeControl.iterator();
            JSONObject entity = null;
            while (t.hasNext()) {
                entity = (JSONObject) t.next();
                try {
                    Properties.ChargeControl.Builder c = Properties.ChargeControl.newBuilder();
                    c.setSite(Properties.ChargeControl.ChargeSite.valueOf(
                            "CHARGE_SITE_" + entity.getString("site").toUpperCase()));
                    c.setChargeStatus(Properties.ChargeControl.ChargeStatus.valueOf(
                            "CHARGE_STATUS_" + entity.getString("status").toUpperCase()));
                    c.setBusiness(Properties.ChargeControl.ChargeBusinessType.valueOf(
                            "CHARGE_BUSINESS_TYPE_" + entity.getString("business").toUpperCase()));
                    c.setPayMark(Common.PayMark.valueOf(entity.getString("pay_mark")));
                    if (StringUtils.isNotBlank(entity.getString("pay_mark_url"))) {
                        c.setPayMarkUrl(entity.getString("pay_mark_url"));
                    }
                    c.setIsSupportTvod(entity.getBoolean(IS_SUPPORT_TVOD));
                    c.setIsSupportMonthly(entity.getBoolean(IS_SUPPORT_MONTHLY));
                    c.setIsSupportTvodCoupon(entity.getBoolean(IS_SUPPORT_TVOD_COUPON));
                    c.setIsSupportPackage(entity.getBoolean(IS_SUPPORT_PACKAGE));
                    c.setIsFreeProbation(entity.getBoolean("is_free_probation"));
                    c.setFreeProbationType(Properties.Boss.FreeProbationType.valueOf(entity.getString("free_probation_type")));
                    if (entity.containsKey(TVOD)) {
                        Properties.Boss.Tvod.Builder tvodBuilder = Properties.Boss.Tvod.newBuilder();
                        JSONObject tvodObject = entity.getJSONObject(TVOD);
                        if (tvodObject.containsKey(CHARGEBASE_ORIGINAL_PRICE)) {
                            tvodBuilder.setOriginalPrice(tvodObject.getIntValue(CHARGEBASE_ORIGINAL_PRICE));
                        }

                        if (tvodObject.containsKey(CHARGEBASE_SETTLEMENT_PRICE)) {
                            tvodBuilder.setSettlementPrice(tvodObject.getIntValue(CHARGEBASE_SETTLEMENT_PRICE));
                        }

                        if (tvodObject.containsKey(CHARGEBASE_VALID_TIME)) {
                            tvodBuilder.setValidTime(tvodObject.getString(CHARGEBASE_VALID_TIME));
                        }
                        c.setTvod(tvodBuilder);
                    }
                    chargeBaseBuilder.addChargeControl(c);
                } catch (Exception e) {
                    logger.error("[fillLiveEpisodeChargeBase] exception = [qipuId=" + tProgram.getQipuId() + "]", e);
                }
            }
        }

        liveBuilder.setChargeBase(chargeBaseBuilder);
    }


    public void fillLiveEpisodeSport(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {

        List<TProgramBase> list = tProgram.getRelationList();
        Properties.LiveSports.Builder builderLiveSport = Properties.LiveSports.newBuilder();
        boolean isSport = tProgram.getType() == Common.LiveProgramType.SPORTS_PROGRAM_VALUE;
        if (isSport) {
            if (list != null && list.size() > 0) {
                for (TProgramBase tBase : list) {
                    if (tBase.getType() == 3) {
                        Properties.LiveSports.Part.Builder builderLiveSportPart = Properties.LiveSports.Part.newBuilder();
                        builderLiveSportPart.setName(tBase.getValue());
                        builderLiveSportPart.setScore((int) tBase.getKey());

                        builderLiveSport.addPart(builderLiveSportPart);
                    } else if (tBase.getType() == 4) {
                        builderLiveSport.addCollectionId(tBase.getKey());
                    }
                }
            }
        }
        //      builderLiveSport.s

        liveBuilder.setLiveSports(builderLiveSport);


    }

    public void fillMatchSummary(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        if (tProgram.getMatchSummary() != null && tProgram.getMatchSummary().length() > 0) {
            knowledge.pub.Metadatas.MatchSummary.Builder matchSummaryBuilder = knowledge.pub.Metadatas.MatchSummary.newBuilder();
            try {
                JSONObject jsonObject = JSONObject.parseObject(tProgram.getMatchSummary());
                long matchId = jsonObject.getLongValue("id");
                matchSummaryBuilder.setId(matchId);
                String matchTitle = jsonObject.getString("title");
                matchSummaryBuilder.setTitle(matchTitle);
                long startTime = jsonObject.getLongValue("start");
                Calendar c = Calendar.getInstance();
                c.setTimeInMillis(startTime);
                knowledge.pub.Common.Date.Builder dateBuilder = knowledge.pub.Common.Date.newBuilder();
                dateBuilder.setYear(c.get(Calendar.YEAR));
                dateBuilder.setMonth(c.get(Calendar.MONTH) + 1);
                dateBuilder.setDay(c.get(Calendar.DAY_OF_MONTH));
                dateBuilder.setHour(c.get(Calendar.HOUR_OF_DAY));
                dateBuilder.setMinute(c.get(Calendar.MINUTE));
                dateBuilder.setSecond(c.get(Calendar.SECOND));
                matchSummaryBuilder.setStartDate(dateBuilder);
            } catch (Exception e) {
                logger.error("fillMatchSummary [qipuId=" + tProgram.getQipuId() + "]", e);
            }
            liveBuilder.setMatchSummary(matchSummaryBuilder);
        }
    }

    public void fillAdvert(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        if (tProgram.getAdvertEnable() > 0) {
            List<ProgramAdvert> list = programService.findAdvertByfQipuId(tProgram.getQipuId());
            if (list.size() > 0) {
                ProgramAdvert advert = list.get(0);
                Metadatas.AdSummary.Builder builder = knowledge.pub.Metadatas.AdSummary.newBuilder();
                builder.setStartTime(DateTimeUtil.parseLongFormat(tProgram.getStartPlayTime()) - DateTimeUtil.SECOND * advert.getDuration());
                //            builder.setTimeLength(advert.getDuration());
                builder.setUuid(advert.getUuid());
                liveBuilder.addAdSummary(builder);
            }

        }
    }

    public void fillProgramLogo(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        if (StringUtils.isNotEmpty(tProgram.getDefaultLogoUrl())) {
            Common.KeyValuePair.Builder keyValuePairBuilder = Common.KeyValuePair.newBuilder();
            keyValuePairBuilder.setName("imageformat_liveepisode_logo");
            keyValuePairBuilder.setValue(tProgram.getDefaultLogoUrl());
            liveBuilder.addKeyValuePair(keyValuePairBuilder.build());

            Properties.LocaleImage.Builder localeImageBuilder = Properties.LocaleImage.newBuilder();
            localeImageBuilder.setType(Properties.LocaleImage.ImageType.COVER);
            localeImageBuilder.setLanguage(Common.Language.zh);
            localeImageBuilder.setImageUrl(tProgram.getDefaultLogoUrl());
            liveBuilder.addLocaleImage(localeImageBuilder);
        }

        if (tProgram.getSnapShotType() == 1) {
            if (StringUtils.isNotEmpty(tProgram.getSnapPicUrl())) {
                Properties.LocaleImage.Builder localeImageBuilder = Properties.LocaleImage.newBuilder();
                localeImageBuilder.setType(Properties.LocaleImage.ImageType.PREVIEW);
                localeImageBuilder.setLanguage(Common.Language.zh);
                localeImageBuilder.setImageUrl(tProgram.getSnapPicUrl());
                liveBuilder.addLocaleImage(localeImageBuilder);
            }
        }

    }

    public void fillLiveTempOther(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        List<TProgramBase> list = tProgram.getRelationList();
        if (list != null && list.size() > 0) {
            for (TProgramBase tBase : list) {
                if (tBase.getType() == 201) {
                    Common.KeyValuePair.Builder keyValuePairBuilder = Common.KeyValuePair.newBuilder();
                    keyValuePairBuilder.setName(LIVE_TEMP_OTHER);
                    keyValuePairBuilder.setValue(tBase.getValue());
                    liveBuilder.addKeyValuePair(keyValuePairBuilder.build());
                    break;
                }
            }
        }
    }

    public void fillResourceId(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        if (StringUtils.isNotBlank(tProgram.getResourceId())) {
            Common.KeyValuePair.Builder keyValuePairBuilder = Common.KeyValuePair.newBuilder();
            keyValuePairBuilder.setName(MULTI_LIVE_RESOURCE_ID);
            keyValuePairBuilder.setValue(tProgram.getResourceId());
            liveBuilder.addKeyValuePair(keyValuePairBuilder.build());
        }
    }

    //200022319_0,201196719_0,200022219_0,200015019_0,200003519_200008119,200000619,200003819_0,200003819_200031319
    public void fillProgramTag(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        if (StringUtils.isNotBlank(tProgram.getProgramTag())) {
            List<String> list = new ArrayList<String>();
            String[] tagArray = tProgram.getProgramTag().split(",");
            if (tagArray.length > 0) {
                for (String channelTag : tagArray) {
                    String[] tags = channelTag.split("_");
                    if (tags.length == 1) {
                        list.add("Tag_Pps_Category_" + tags[0]);
                    } else if (tags.length == 2) {
                        list.add("Tag_Pps_Category_" + (Integer.valueOf(tags[1]) == 0 ? tags[0] : tags[1]));
                    }
                }
            }
            liveBuilder.addAllTag(list);
        }
    }

//    public void fillOnlineTest(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
//        if (tProgram.getTest() == 1) {
//            Common.KeyValuePair.Builder keyValuePairBuilder = Common.KeyValuePair.newBuilder();
//            keyValuePairBuilder.setName(ONLINE_TEST_LIVEEPISODE);
//            keyValuePairBuilder.setValue("IS_ONLINE_TEST");
//            liveBuilder.addKeyValuePair(keyValuePairBuilder.build());
//        }
//    }

    public void fillPuyu(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        Properties.Puyu.Builder puyu = Properties.Puyu.newBuilder();
        if (!tProgram.getBarCode().isEmpty()) {
            WritePuYuQipuData puyuQipuData = ApiPuYuRequestUtil.decodeForBarCode(tProgram.getBarCode());
            if (puyuQipuData != null) {
                puyu.setContractBarcode(puyuQipuData.getBarCode());
                puyu.setStartTime(puyuQipuData.getStartTime());
                puyu.setEndTime(puyuQipuData.getEndTime());
                puyu.setContractName(puyuQipuData.getContractNumber());
                Properties.Puyu.CopyrightOwner.Builder owner = Properties.Puyu.CopyrightOwner.newBuilder();
                owner.setId(puyuQipuData.getCprOwnerId());
                owner.setName(puyuQipuData.getCprName());
                puyu.addCopyrightOwner(owner);
                puyu.setProgramId(puyuQipuData.getVideoId());
                puyu.setProgramName(puyuQipuData.getVideoName());
                puyu.setContractCode(puyuQipuData.getContractId());
            } else {
                logger.info("[setPuYuToQipu] puyu is null entityId:" + tProgram.getQipuId() + "; barCode:" + tProgram.getBarCode());
            }
        }
        liveBuilder.setPuyu(puyu);
    }

    private void doCheckQipuTask() {
        try {
            List<SimpleTask> resultList = simpleTaskService.findList(SimpleTaskType.QIPU_ACCESS_CHECK.getTypeIndex(), SimpleTaskStatus.WAIT.getStatusIndex());
            if (resultList == null || resultList.size() == 0) {
                logger.info("[result empty] resultList == null :" + (resultList == null));
                return;
            }
            Collections.reverse(resultList);
            long current = System.currentTimeMillis();
            List<SimpleTask> updateList = new ArrayList<SimpleTask>();
            Map<Long, SimpleTask> checkMap = new HashMap<Long, SimpleTask>();
            for (SimpleTask simpleTask : resultList) {
                if (current > simpleTask.getExpireTime().getTime()) {
                    simpleTask.setTaskStatus(SimpleTaskStatus.EXPIRED.getStatusIndex());
                    updateList.add(simpleTask);
                } else {
                    if (!checkMap.containsKey(simpleTask.getEntityId())) {
                        checkMap.put(simpleTask.getEntityId(), simpleTask);
                    } else {
                        simpleTask.setTaskStatus(SimpleTaskStatus.OVERRIDE.getStatusIndex());
                        updateList.add(simpleTask);
                    }
                }
            }
            if (updateList.size() > 0) {
                simpleTaskService.batchUpdateList(updateList);
            }
            if (checkMap.size() > 0) {
                TProgram tProgram = null;
                updateList.clear();
                for (SimpleTask simpleTask : checkMap.values()) {
                    try {
                        tProgram = programService.findTProgramById(simpleTask.getEntityId(), false);
                        if (checkCanWriteEpisodeSummary(tProgram)) {

                            int result = setLiveEpisodeBaseToQipu(tProgram);
                            if (!checkFail(result, "phase  setLiveEpisodeBaseToQipu")) {
                                simpleTask.setTaskStatus(SimpleTaskStatus.COMPLETE.getStatusIndex());
                                simpleTask.setCompleteTime(new Timestamp(System.currentTimeMillis()));
                                logger.info("[async qipu setLiveEpisodeBaseToQipu] complete" + tProgram.getId());
                                updateList.add(simpleTask);
                            }
                        }
                    } catch (Exception e) {
                        logger.error("Exception={} ,sid=" + simpleTask.getId(), e);
                    }
                }
                if (updateList.size() > 0) {
                    simpleTaskService.batchUpdateList(updateList);
                }
            }

        } catch (Exception e) {
            logger.error("exception = {}", e);
        }
    }

    public void afterPropertiesSet() throws Exception {
        logger.info("afterPropertiesSet");
        asyncService.init();
    }

    public class AsyncServiceImpl extends AsyncService implements IHeartBeat {
        private final static int HEARTBEAT_DELAY = 300000; //
        private long heartBeatTime = 0;

        protected boolean queryEnable() {
            return getEnable("nodeLive");
        }

        @Override
        public void tick(long now) {
            if (now - heartBeatTime >= HEARTBEAT_DELAY) {
                heartBeatTime = now;
                this.accept(new IAsyncTask() {
                    @Override
                    public void doTask() {
                        doCheckQipuTask();
                    }
                });
            }
        }

        public void init() {
            HeartBeatCenter.add(this);
        }

        public void addAsyncTask(TProgram tProgram) {
            //  this.accept(new);
            SimpleTask simpleTask = new SimpleTask();
            simpleTask.setServerIp(RequestUtils.getLoadlIpByOS());
            simpleTask.setWorkIp(simpleTask.getServerIp());
            simpleTask.setTaskStatus(SimpleTaskStatus.WAIT.getStatusIndex());
            simpleTask.setTaskType(SimpleTaskType.QIPU_ACCESS_CHECK.getTypeIndex());
            simpleTask.setCreateTime(new Timestamp(System.currentTimeMillis()));
            simpleTask.setEntityId(tProgram.getId());
            simpleTask.setExpireTime(new Timestamp(System.currentTimeMillis() + 2 * DateTimeUtil.DAY_TIME));
            simpleTaskService.saveTask(simpleTask);
        }
    }

    public void fillProgramSubscribe(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        Common.KeyValuePair.Builder keyValuePairBuilder = Common.KeyValuePair.newBuilder();
        keyValuePairBuilder.setName("is_subscribe");
        keyValuePairBuilder.setValue(String.valueOf(tProgram.getSubscribe()));
        liveBuilder.addKeyValuePair(keyValuePairBuilder.build());
    }

    public void fillProgramQisu(TProgram tProgram, Knowledge.LiveEpisode.Builder liveBuilder) {
        Common.Qisu.Builder qisuBuilder = Common.Qisu.newBuilder();
        qisuBuilder.setUrl(String.format(QISU_URL_TEMPLATE,
                String.valueOf(tProgram.getQipuId()),
                tProgram.getBossStatus().equals(ProgramData.PAIED_AVAILABLE) ? "true" : "false"));
        liveBuilder.setQisu(qisuBuilder);
    }
}
